﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using System.Reactive;
using System.Reactive.Concurrency;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using System.Reactive.Subjects;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace SimpleActor.Test
{
    [TestClass]
    public class ExpressionHelperTest
    {
        [TestMethod]
        public void GetMemberNameTest()
        {
            Expression<Func<ITestServant, Task>> action = s => s.Action0();
            Expression<Func<ITestServant, IObservable<int>>> prop = s => s.Prop;
            Expression<Func<ITestServant, Task>> e = null;


            ExpressionHelper.GetMemberName(action).Is("Action0");
            ExpressionHelper.GetMemberName(prop).Is("Prop");

            AssertEx.Throws<ArgumentNullException>(() => ExpressionHelper.GetMemberName(e));
        }

        private void ValueIncludedTest(byte param)
        {
            Expression<Func<ITestServant, Task>> action0 = s => s.Action0();
            
            Expression<Func<ITestServant, byte, Task>> action1a = (s, p) => s.Action1(p);
            Expression<Func<ITestServant, Task>> action1b = s => s.Action1(0);
            Expression<Func<ITestServant, Task>> action1c = s => s.Action1(param);

            Expression<Func<ITestServant, byte, short, int, long, Task>> action4a = (s, p1, p2, p3, p4) => s.Action4(p1, p2, p3, p4);
            Expression<Func<ITestServant, byte, short, int, Task>> action4b = (s, p1, p2, p3) => s.Action4(p1, p2, p3, 0);
            Expression<Func<ITestServant, short, int, long, Task>> action4c = (s, p1, p2, p3) => s.Action4(param, p1, p2, p3); 

            Expression<Func<ITestServant, IObservable<int>>> prop = s => s.Prop;

            Expression<Func<ITestServant, Task>> nullex = null;
            Expression<Func<int, int, int>> plus = (x, y) => x + y;

            ExpressionHelper.ValueIncluded(action0).IsFalse();

            ExpressionHelper.ValueIncluded(action1a).IsFalse();
            ExpressionHelper.ValueIncluded(action1b).IsTrue();
            ExpressionHelper.ValueIncluded(action1c).IsTrue();

            ExpressionHelper.ValueIncluded(action4a).IsFalse();
            ExpressionHelper.ValueIncluded(action4b).IsTrue();
            ExpressionHelper.ValueIncluded(action4c).IsTrue();

            ExpressionHelper.ValueIncluded(prop).IsFalse();

            AssertEx.Throws<ArgumentNullException>(() =>
            {
                ExpressionHelper.ValueIncluded(nullex);
            });

            AssertEx.Throws<ArgumentException>(() =>
            {
                ExpressionHelper.ValueIncluded(plus);
            });
        }

        [TestMethod]
        public void ValueIncludedTest()
        {
            ValueIncludedTest(0);
        }
    }
}
